﻿module Sustainalytics.EsgRatings.Admin {

    import Common = Sustainalytics.Common;
    import CommonAdmin = Sustainalytics.Common.Admin;
    import LRTM = Sustainalytics.LRTM;
    import AdminAccounts = Sustainalytics.Accounts.Admin;

    export class WeightMatrixAddEditController {

        public selectedFile: any;
        public loading: boolean;

        public weightMatrixUploadErrors: string;

        constructor(
            private $rootScope: any,
            private $scope: ng.IScope,
            private $modal: Common.IModal,
            private $modalInstance: Common.IModalInstance,

            //pre-populated
            private accountWeightMatrices: WeightMatrix[],
            private accountScheduledWeightMatrices: WeightMatrix[],
            private totalSlots: number,
            private selectedAccount: AdminAccounts.AccountsDto,
            public editedWeightMatrix: WeightMatrix,


            private WeightMatricesService : IWeightMatricesService,
            private LongRunningTaskManagerService: LRTM.LongRunningTaskManagerService,
            private notificationFactory: Common.INotificationFactory)
        {

            var ctx = this;
            $scope['addEditWeightMatrix'] = this;

        }

        public onSelectExcel($files): any {
            var ctx = this;
            ctx.selectedFile = null;
            var file = $files[0]; // html assures is just 1
            if (file && (file.type != "application/vnd.ms-excel" && file.type != "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
                ctx.notificationFactory.error("", "Please upload an excel type file.");
            }
            else if (file) {
                ctx.selectedFile = file;
            }

            if (!ctx.selectedFile) {
                this.weightMatrixUploadErrors = null;
            }
        }

        public cancel()
        {
            var ctx = this;
            ctx.$modalInstance.close({reload:false, err: null});
        }

        public saveAndOrUpload() {

            var ctx = this;
            var fileDefined = false;

            if (ctx.selectedAccount.platformTier === AdminAccounts.AccessLevel.Tier3) {
                ctx.notificationFactory.error("", "A Tier 3 Type customer cannot upload custom matrices!");
                return;
            }

            var files = $('#customWeightMatrixFile').get(0)['files'];
            if (files != undefined && files.length > 0)
                fileDefined = true;

            if (files == undefined && $('#customWeightMatrixFile').val() != undefined && $('#customWeightMatrixFile').val() != "")
            {
                fileDefined = true;
                files = [$('#customWeightMatrixFile').val()];
            }

            if (!ctx.editedWeightMatrix.name || ctx.editedWeightMatrix.name.length == 0) {
                ctx.notificationFactory.error("", "Please assign a weight matrix name !");
                return;
            }

            // validations for edit custom weight matrix
            var foundWeightMatrices = ctx.accountWeightMatrices.filter(function (el) {
                return el.name == ctx.editedWeightMatrix.name;
            });

            var foundScheduledWeightMatrices = ctx.accountScheduledWeightMatrices.filter(function (el) {
                return el.name == ctx.editedWeightMatrix.name;
            });

            //make sure you validate the name here to be unique among the matrices of this account
            if (!ctx.editedWeightMatrix.id
                && (foundWeightMatrices.length > 0 || foundScheduledWeightMatrices.length > 0))
            {
                ctx.notificationFactory.error("", "Matrices names should be unique per account !");
                ctx.$rootScope['loading'] = false;
                return;
            }

            //validations for new custom matrix
            if (!ctx.editedWeightMatrix.id) {

                if (!fileDefined) {
                    ctx.notificationFactory.error("", "No weight matrix selected !");
                    ctx.$rootScope['loading'] = false;
                    return;
                }

                //validate count threshold
                //max 100 matrices per platform
                if (ctx.totalSlots + 1 === 100) {
                    ctx.notificationFactory.error("", "We do not support more than 100 matrices on GAP !");
                    ctx.$rootScope['loading'] = false;
                    return;
                }


                //Tier 1 max 5
                if (ctx.selectedAccount.platformTier == AdminAccounts.AccessLevel.Tier1 &&
                    (ctx.accountScheduledWeightMatrices.length + ctx.accountWeightMatrices.length) >= 5) {
                    ctx.notificationFactory.error("", "A Tier 1 access level account cannot have more than 5 custom weight matrices !");
                    ctx.$rootScope['loading'] = false;
                    return;
                }

                //Tier 2 max 2
                if (ctx.selectedAccount.platformTier == AdminAccounts.AccessLevel.Tier2 &&
                    (ctx.accountScheduledWeightMatrices.length + ctx.accountWeightMatrices.length) >= 2) {
                    ctx.notificationFactory.error("", "A Tier 2 access level account cannot have more than 2 custom weight matrices !");
                    ctx.$rootScope['loading'] = false;
                    return;
                }
            }

            //only for editing name (for editing actual excel we need to re-schedule ESGInputFile)
            if (ctx.editedWeightMatrix.id && !fileDefined) {
                var promiseEditName = ctx.WeightMatricesService.updateCustomWeightMatrix(ctx.editedWeightMatrix);
                promiseEditName.finally(() => {
                    ctx.$rootScope['loading'] = false;
                    ctx.$modalInstance.close({ reload: true, err: null });
                });
            }

            //when inserting / editing matrix and selecting a custom matrix to insert/update
            if (fileDefined)
            {
                var promise = ctx.doWeightMatrixTaskUpload(ctx.editedWeightMatrix, files);
                promise.finally(() => {
                    ctx.$rootScope['loading'] = false;
                    //ctx.$modalInstance.close({ reload: true, err: ctx.weightMatrixUploadErrors });
                });
            }
        }

        private doWeightMatrixTaskUpload(uploadDto: WeightMatrix, files: any[]): ng.IPromise<string> {
            var ctx = this;
            ctx.$rootScope['loading'] = true;

            var taskTitle = "Upload " + uploadDto.name + " weight matrix";

            var promise = ctx.LongRunningTaskManagerService.runTaskWithUpload(
                taskTitle, // title
                JSON.stringify(uploadDto), // paramJson
                Sustainalytics.LRTM.LongRunningTaskTypeEnum.WeightMatrixUpload, // taskType
                files, // files
                null, // uploadProgressFunc
                true, // isDownload
                (id, newStatus, oldStatus, taskInstance) => ctx.statusChangedCallback(id, newStatus, oldStatus, taskInstance) // statusChangedCallback
                );
            return promise;
        }

        private statusChangedCallback(taskInstanceId: string, newStatus: LRTM.LongRunningTaskInstanceStatusEnum, oldStatus: LRTM.LongRunningTaskInstanceStatusEnum, taskInstance: LRTM.LongRunningTaskInstance): void {
            var ctx = this;

            if (newStatus === LRTM.LongRunningTaskInstanceStatusEnum.Failed) {
                var promise = ctx.LongRunningTaskManagerService.getResult(taskInstanceId, false);
                promise.then(function (res) {
                    ctx.$rootScope['loading'] = false;

                    var serverErrors = taskInstance.status.taskStatus.errors;
                    if (serverErrors && serverErrors.length > 0) {

                        //serverErrors.forEach(serverErr => {
                        //    taskInstance.errors.push(serverErr.arguments[0]);
                        //});
                        //ctx.weightMatrixUploadErrors = taskInstance.errors[0];

                        ctx.weightMatrixUploadErrors = serverErrors[0].arguments[0];
                        ctx.$modalInstance.close({ reload: false, err: ctx.weightMatrixUploadErrors });
                    }
                });
            }

            // display result
            if (newStatus == LRTM.LongRunningTaskInstanceStatusEnum.Finished) {
                var promise = ctx.LongRunningTaskManagerService.getResult(taskInstanceId, false);
                promise.then(function (res) {
                    ctx.$rootScope['loading'] = false;

                    //console.log(taskInstance);
                    //if (taskInstance.status.taskStatus.details && taskInstance.status.taskStatus.details.length > 0) {
                        ////ctx.cancel(newStatus);
                    //}
                    ctx.$modalInstance.close({ reload: true, err: null });
                });
            }

        }
    }

    var mod = angular.module(esgRatingsAdminModuleName);

    mod.controller('WeightMatrixAddEditController',
        ['$rootScope', '$scope', '$modal', '$modalInstance', 'accountWeightMatrices', 'accountScheduledWeightMatrices', 'totalSlots', 'selectedAccount','editedWeightMatrix', 'WeightMatricesService', 'LongRunningTaskManagerService', 'notificationFactory', WeightMatrixAddEditController]);
}
